pub mod t2_0 {
    use regex::Regex;
    use rust_test::common::*;

    pub fn tt() -> Result<(), Box<dyn std::error::Error>> {
        tt1()?;

        Ok(())
    }

    #[mydbginfo]
    pub fn tt1() -> Result<(), Box<dyn std::error::Error>> {
        let pattern = r"solversdk_develop_.+\.(zip|rar|7z)";
        let re = Regex::new(pattern).unwrap();
        let target = "solversdk_develop_2504172254_211c7621.zip";

        if re.is_match(target) {
            blue_println!("正则表达式匹配成功: {} => {}", pattern, target);
            let captures = re.captures(target).unwrap();
            for i in 0..captures.len() {
                println!("第 {} 个捕获组: {}", i, captures.get(i).unwrap().as_str());
            }
        } else {
            yellow_println!("正则表达式匹配失败: {} => {}", pattern, target);
        }

        Ok(())
    }
}

// =================================== trait 测试
pub mod t2_1 {
    use rust_test::common::*;
    use std::fmt;
    use std::fmt::Display;

    pub trait Draw {
        fn draw(&self);
    }

    impl Draw for u8 {
        fn draw(&self) {
            blue_println!("Drawing u8: {}", *self)
        }
    }

    impl Draw for f64 {
        fn draw(&self) {
            blue_println!("Drawing f64: {}", *self)
        }
    }

    // 若 T 实现了 Draw 特征,  则调用该函数时传入的 Box<T> 可以被隐式转换成函数参数签名中的 Box<dyn Draw>
    fn draw1(x: Box<dyn Draw>) {
        // 由于实现了 Deref 特征, Box 智能指针会自动解引用为它所包裹的值, 然后调用该值对应的类型上定义的 `draw` 方法
        x.draw();
    }

    fn draw2(x: &dyn Draw) {
        x.draw();
    }

    //------------------ trait 对象 测试
    #[mydbginfo]
    pub fn tt() -> Result<(), Box<dyn std::error::Error>> {
        let x = 1.1f64;
        // do_something(&x);
        let y = 8u8;

        // x 和 y 的类型 T 都实现了 `Draw` 特征, 因为 Box<T> 可以在函数调用时隐式地被转换为特征对象 Box<dyn Draw>
        // 基于 x 的值创建一个 Box<f64> 类型的智能指针, 指针指向的数据被放置在了堆上
        draw1(Box::new(x));
        // 基于 y 的值创建一个 Box<u8> 类型的智能指针
        draw1(Box::new(y));
        draw2(&x);
        draw2(&y);

        Ok(())
    }

    //====================================== trait 对象
    pub struct Button {
        pub width: u32,
        pub height: u32,
        pub label: String,
    }

    impl Draw for Button {
        fn draw(&self) {
            // 绘制按钮的代码
            blue_println!(
                "Drawing Button: width={}, height={}, label={}",
                self.width,
                self.height,
                self.label
            );
        }
    }

    struct SelectBox {
        width: u32,
        height: u32,
        options: Vec<String>,
    }

    impl Draw for SelectBox {
        fn draw(&self) {
            // 绘制SelectBox的代码
            blue_println!(
                "Drawing SelectBox: width={}, height={}, options={:?}",
                self.width,
                self.height,
                self.options
            );
        }
    }

    pub struct Screen {
        pub components: Vec<Box<dyn Draw>>,
    }
    // 再来为 Screen 定义 run 方法, 用于将列表中的 UI 组件渲染在屏幕上:
    impl Screen {
        pub fn run(&self) {
            for component in self.components.iter() {
                component.draw();
            }
        }
    }

    //------------------ trait 对象的 vec
    #[mydbginfo]
    pub fn tt2() {
        let screen = Screen {
            components: vec![
                Box::new(SelectBox {
                    width: 75,
                    height: 10,
                    options: vec![String::from("Yes"), String::from("Maybe"), String::from("No")],
                }),
                Box::new(Button {
                    width: 50,
                    height: 10,
                    label: String::from("OK"),
                }),
            ],
        };

        screen.run();
    }

    //================================== trait 包含泛型参数
    pub trait MyT<T: Display> {
        fn prt(&self, t: &T);
    }

    pub struct MyStr {
        msg: String,
    }

    impl MyT<i32> for MyStr {
        fn prt(&self, t: &i32) {
            blue_println!("tag i32: {}, MyStr: {}", t, self.msg);
        }
    }

    impl MyT<f64> for MyStr {
        fn prt(&self, t: &f64) {
            blue_println!("tag f64: {}, MyStr: {}", t, self.msg);
        }
    }

    #[mydbginfo]
    pub fn tt3() {
        let a = MyStr {
            msg: String::from("EL PSI CONGAROO!"),
        };

        MyT::prt(&a, &0i32);
        MyT::prt(&a, &1.0f64);
    }

    //------------------ trait of泛型的对象
    #[mydbginfo]
    pub fn tt4() {
        let av: Vec<Box<dyn MyT<i32>>> = vec![
            Box::new(MyStr {
                msg: String::from("i32, my str 1"),
            }),
            Box::new(MyStr {
                msg: String::from("i32, my str 2"),
            }),
        ];

        for item in av.iter() {
            item.prt(&2i32);
        }
    }

    //========================== stable 版本不支持特化
    /*
    pub trait MyT2 {
        fn prt<T: Display>(&self, t: &T);
    }

    pub struct MyStr2 {
        msg: String,
    }

    impl MyT2 for MyStr2 {
        default fn prt<T: Display>(&self, t: &T) {
            println!("tag i32: {}, MyStr: {}", t, self.msg);
        }
    }

    impl MyT2 for MyStr2 {
        fn prt<T: Display>(&self, t: &T) {
            println!("tag i32: {}, MyStr: {}", t, self.msg);
        }
    }
    */

    //================================== 调用同名的方法
    trait Pilot {
        fn fly(&self);
        fn prt();
    }

    trait Wizard {
        fn fly(&self);
        fn prt();
    }

    struct Human;

    impl Pilot for Human {
        fn fly(&self) {
            blue_println!("This is your captain speaking.");
        }
        fn prt() {
            blue_println!("Pilot trait method prt called.");
        }
    }

    impl Wizard for Human {
        fn fly(&self) {
            blue_println!("Up!");
        }
        fn prt() {
            blue_println!("Wizard trait method prt called.");
        }
    }

    impl Human {
        fn fly(&self) {
            blue_println!("*waving arms furiously*");
        }
        pub fn prt() {
            blue_println!("Human type method prt called.");
        }
    }

    #[mydbginfo]
    pub fn tt5() {
        let person = Human;
        Pilot::fly(&person); // 调用Pilot特征上的方法
        Wizard::fly(&person); // 调用Wizard特征上的方法
        person.fly(); // 调用Human类型自身的方法

        //----- 完全限定语法
        // <Type as Trait>::function(receiver_if_method, next_arg, ...);
        my_sep_sub();
        <Human as Pilot>::prt();
        <Human as Wizard>::prt();
        Human::prt();
    }

    //================================= 特征定义中的特征约束
    trait OutlinePrint: Display {
        fn outline_print(&self) {
            let output = self.to_string();
            let len = output.len();
            println!("{}", "*".repeat(len + 4));
            println!("*{}*", " ".repeat(len + 2));
            println!("* {} *", output);
            println!("*{}*", " ".repeat(len + 2));
            println!("{}", "*".repeat(len + 4));
        }
    }

    struct Point {
        x: i32,
        y: i32,
    }

    impl OutlinePrint for Point {}

    impl fmt::Display for Point {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "({}, {})", self.x, self.y)
        }
    }

    //---------------- trait 定义中的 trait 约束
    #[mydbginfo]
    pub fn tt6() {
        let p = Point { x: 3, y: 7 };
        p.outline_print();
    }

    //=========================== 在外部类型上实现外部特征(newtype)
    struct Wrapper(Vec<String>);

    impl fmt::Display for Wrapper {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "len = {}, val = [{}]", self.0.len(), self.0.join(", "))
        }
    }

    #[mydbginfo]
    pub fn tt7() {
        let w = Wrapper(vec![String::from("hello"), String::from("world")]);
        blue_println!("w: {}", w);
    }
}

// ****************************** vector 测试
pub mod t2_2 {
    use regex::Regex;
    use rust_test::common::*;

    //================== vector 测试
    #[mydbginfo]
    pub fn tt1() {
        // Vec 只能存储相同的类型
        let v = vec![Some(1), Some(2), Some(3)];

        blue_println!("v: {:?}", v);
    }

    //================== vector 借用数组元素
    #[mydbginfo]
    pub fn tt2() {
        let mut v = vec![1, 2, 3, 4, 5];
        let first = &v[0];
        blue_println!("The first element is: {first}");
        v.push(6);
        let first = &v[0]; // 必须重新借用, 否则无法通过编译
        blue_println!("The first element is: {first}");
    }

    //================== vector 迭代遍历
    #[mydbginfo]
    pub fn tt3() {
        let mut v = vec![1, 2, 3];
        blue_println!("Before: {:?}", v);
        for i in &mut v {
            // i += 10; // wrong, 需要解引用
            *i += 10
        }
        blue_println!("After : {:?}", v);
    }

    //================== 通过 枚举 存储不同类型的元素
    #[derive(Debug)]
    enum IpAddr {
        V4(String),
        V6(String),
    }
    fn show_addr(ip: IpAddr) {
        blue_println!("{:?}", ip);
    }

    #[mydbginfo]
    pub fn tt4() {
        let v = vec![
            //
            IpAddr::V4("127.0.0.1".to_string()),
            IpAddr::V6("::1".to_string()),
        ];

        for ip in v {
            show_addr(ip)
        }
    }

    //================== 通过 trait 对象 存储不同类型的元素
    trait IpAddr2 {
        fn display(&self);
    }

    struct V4(String);
    impl IpAddr2 for V4 {
        fn display(&self) {
            blue_println!("ipv4: {:?}", self.0)
        }
    }
    struct V6(String);
    impl IpAddr2 for V6 {
        fn display(&self) {
            blue_println!("ipv6: {:?}", self.0)
        }
    }

    #[mydbginfo]
    pub fn tt5() {
        let v: Vec<Box<dyn IpAddr2>> = vec![
            //
            Box::new(V4("127.0.0.1".to_string())),
            Box::new(V6("::1".to_string())),
        ];

        for ip in v {
            ip.display();
        }
    }

    //================== vector 预分配容量
    #[mydbginfo]
    pub fn tt6() {
        let mut v = Vec::with_capacity(10);
        v.extend([1, 2, 3]); // 附加数据到 v
        blue_println!("Vector 长度是: {}, 容量是: {}", v.len(), v.capacity());

        v.reserve(100); // 调整 v 的容量, 至少要有 100 的容量
        blue_println!("Vector(reserve) 长度是: {}, 容量是: {}", v.len(), v.capacity());

        v.shrink_to_fit(); // 释放剩余的容量, 一般情况下, 不会主动去释放容量
        blue_println!("Vector(shrink_to_fit) 长度是: {}, 容量是: {}", v.len(), v.capacity());
    }

    //================== vector 常用操作
    #[mydbginfo]
    pub fn tt7() {
        let mut v = vec![1, 2];
        assert!(!v.is_empty()); // 检查 v 是否为空

        v.insert(2, 3); // 在指定索引插入数据, 索引值不能大于 v 的长度,  v: [1, 2, 3]
        blue_println!("v: {:?}", v);
        assert_eq!(v.remove(1), 2); // 移除指定位置的元素并返回, v: [1, 3]
        blue_println!("v: {:?}", v);
        assert_eq!(v.pop(), Some(3)); // 删除并返回 v 尾部的元素, v: [1]
        blue_println!("v: {:?}", v);
        assert_eq!(v.pop(), Some(1)); // v: []
        blue_println!("v: {:?}", v);
        assert_eq!(v.pop(), None); // 记得 pop 方法返回的是 Option 枚举值
        blue_println!("v: {:?}", v);
        v.clear(); // 清空 v, v: []

        my_sep_sub();
        let mut v1 = [11, 22].to_vec(); // append 操作会导致 v1 清空数据, 增加可变声明
        blue_println!("v1: {:?}", v1);
        v.append(&mut v1); // 将 v1 中的所有元素附加到 v 中, v1: []
        blue_println!("v: {:?}", v);
        v.truncate(1); // 截断到指定长度, 多余的元素被删除, v: [11]
        blue_println!("v: {:?}", v);
        v.retain(|x| *x > 10); // 保留满足条件的元素, 即删除不满足条件的元素
        blue_println!("v: {:?}", v);

        my_sep_sub();
        let mut v = vec![11, 22, 33, 44, 55];
        // 删除指定范围的元素, 同时获取被删除元素的迭代器, v: [11, 55], m: [22, 33, 44]
        blue_println!("v: {:?}", v);
        let mut m: Vec<_> = v.drain(1..=3).collect();
        blue_println!("m: {:?}", m);

        let v2 = m.split_off(1); // 指定索引处切分成两个 vec, m: [22], v2: [33, 44]
        blue_println!("m: {m:?}, v2: {v2:?}");

        // ------ vec切片, 可以作为 数组切片
        my_sep_sub();
        let v = vec![11, 22, 33, 44, 55];
        let slice = &v[1..=3];
        assert_eq!(slice, &[22, 33, 44]);
        blue_println!("v: {v:?}");
        blue_println!("slice: {slice:?}");
    }

    //================== vector 整数排序
    #[mydbginfo]
    pub fn tt8() {
        let mut vec = vec![1, 5, 10, 2, 15];
        vec.sort_unstable();
        assert_eq!(vec, vec![1, 2, 5, 10, 15]);
        blue_println!("Sorted vector: {:?}", vec);
    }

    /*
    在浮点数当中, 存在一个 NAN 值, 这个值无法与其他的浮点数进行对比,
    因此, 浮点数类型并没有实现全数值可比较 Ord 的特性, 而是实现了部分可比较的特性 PartialOrd.
    如此, 如果我们确定在我们的浮点数数组当中, 不包含 NAN 值, 那么我们可以使用 partial_cmp 来作为大小判断的依据.
    */
    //================== vector 浮点数排序
    #[mydbginfo]
    pub fn tt9() {
        let mut vec = vec![1.0, 5.6, 10.3, 2.0, 15f32];
        vec.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
        assert_eq!(vec, vec![1.0, 2.0, 5.6, 10.3, 15f32]);
        blue_println!("Sorted vector: {:?}", vec);
    }

    //==================== vector, 对 struct 排序
    #[derive(Debug)]
    struct Person {
        name: String,
        age: u32,
    }

    impl Person {
        fn new(name: String, age: u32) -> Person {
            Person { name, age }
        }
    }

    #[mydbginfo]
    pub fn tt10() {
        let mut people = vec![
            Person::new("Zoe".to_string(), 25),
            Person::new("Al".to_string(), 60),
            Person::new("John".to_string(), 1),
        ];
        // 定义一个按照年龄倒序排序的对比函数
        people.sort_unstable_by(|a, b| b.age.cmp(&a.age));

        blue_println!("{:?}", people);
    }
}
